package chord.finder;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.juitar.base.Chord;
import com.juitar.base.Fingering;
import com.juitar.base.Tuning;
import com.juitar.base.fingering.IFingeringBuilder;
import com.juitar.base.fingering.RecursiveFingeringBuilder;
import com.juitar.base.fingering.TextFingering;
import com.juitar.base.utils.Config;

/**
 * Servlet implementation class for Servlet: Finder
 * 
 */
public class Finder extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
	int CHORDS_PER_ROW = 4;
	
	/**
	 * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
	 * methods.
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 */
	protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		
		//debugHeaders(request);

		boolean chrome = false;
		String userAgent = request.getHeader("User-Agent");
		if (userAgent != null && userAgent.contains("Chrome")) {
			chrome = true;
		}
		
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();

		// Read request parameters
		String chordParam = request.getParameter("chord");
		String noteParam = request.getParameter("root");

		if (chordParam == null || chordParam.length()==0) {
			request.getRequestDispatcher("/").forward(request, response);
			return;
		}
		
		Chord ch = null;
		List<Chord> chords = Config.getChords();
		for (Chord chord : chords) {
			if (chord.getName().equalsIgnoreCase(chordParam)) {
				ch = chord;
			}
		}
		if (ch == null) {
			request.getRequestDispatcher("/").forward(request, response);
			return;
		}
		int note = 0;
		try {
			note = Integer.valueOf(noteParam).intValue();
		} catch (NumberFormatException nfe ) {
			request.getRequestDispatcher("/").forward(request, response);
			return;
		}
		Chord chord = new Chord(ch, note);

		Tuning tuning = (Tuning) request.getSession().getAttribute("tuning");
		if (tuning == null) {
			tuning = Tuning.STANDARD;
		}

		IFingeringBuilder builder = new RecursiveFingeringBuilder();
		Collection<Fingering> list = builder.createFingerings(chord, tuning);
		String chordName = chord.getChordName();

		out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
		out.println("<html>");
		out.println("<head>");
		out.print("<link rel=\"stylesheet\" type=\"text/css\" href=");
		if (!chrome) {
			out.println("\"style.css\">");
		} else {
			out.println("\"style-chrome.css\">");
		}
		out.println("<title>" + chordName + " on " + tuning + " tuning" + "</title>");
		out.println("</head>");
		out.println("<body>");

		out.println("<h2>" + chordName + " on " + tuning + " tuning" + "</h2>");
		out.println("Chord notes - <em>" + chord.getNotesText() + "</em>");
		out.println("<br>Chord found " + list.size() + " times");
		out.println("<br><a href='/'>Back to search page</a>");

		Iterator<Fingering> it = list.iterator();
		int firstFret = -1;
		while (it.hasNext()) {
			Fingering f = it.next();
			if (firstFret != f.getFirstFret()) {
				if (firstFret != -1) {
					out.println("</div>");
				}
				firstFret = f.getFirstFret();
				out.println("<h3>Chords at " + firstFret + " position</h3>");
				out.println("<div>");
			}
			String chordTable = HtmlHelper.toHtmlTable(f);
			out.println(chordTable);
			out.println("&nbsp;&nbsp;");
			
		}
		out.println("</div>");
		out.println("</body>");
		out.println("</html>");

		out.close();
	}

	private void debugHeaders(HttpServletRequest request) {
		Enumeration headerNames = request.getHeaderNames();
		while(headerNames.hasMoreElements()) {
			String header = (String) headerNames.nextElement();
			System.out.println(header + ": " +request.getHeader(header));
		}
	}

	private void printChord(final PrintWriter out, final Fingering f) {
		out.println("<b><pre>");
		String[] s = TextFingering.toStrings(f);
		for (int i = 0; i < s.length; i++) {
			out.println(s[i]);
		}
		out.println("</pre></b>");
	}


	/**
	 * Handles the HTTP <code>GET</code> method.
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * Handles the HTTP <code>POST</code> method.
	 * 
	 * @param request
	 *            servlet request
	 * @param response
	 *            servlet response
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		processRequest(request, response);
	}

	/**
	 * Returns a short description of the servlet.
	 */
	public String getServletInfo() {
		return "Short description";
	}
}